' Strict
SuperStrict

' Modules
Import BRL.Map

' Files
Import "Global.bmx"
Import "TLog.bmx"
Import "TInputSystem.bmx"
Import "Utilities/DesktopExt.bmx"

' Includes
Include "TGameState.bmx"

' Singleton
Global game:TGame

' TGame
Type TGame
	' Graphics configuration
	Field gfxWidth:Int
	Field gfxHeight:Int
	Field gfxWidthHalf:Int
	Field gfxHeightHalf:Int
	Field fullscreen:Int
	Field driver:String
	Field audioDriver:String
	Field vsync:Int
	
	Field frameTime:Int
	Field lastFrameTimeUpdate:Int
	Field speed:Int
	
	' Map containing all game state names and references
	Field mapGS:TMap
	
	' Active game state
	Field gameState:TGameState
	
	' Log
	Field logger:TLog
	Field loggerDetail:TLog
	
	' Init
	Method Init()
		' Log
		?Debug
			Self.logger = TLog.Create(StandardIOStream)
		?Not Debug
			Self.logger = TLog.Create(WriteFile(FS_ROOT + "logs/main.txt"))
		?
		
		' Detail Log
		?Debug
			Self.loggerDetail = TLog.Create(StandardIOStream)
		?Not Debug
			Self.loggerDetail = TLog.Create(WriteFile(FS_ROOT + "logs/detail.txt"))
		?
		
		Self.mapGS = CreateMap()
		Self.speed = 0.0
	End Method
	
	' RegisterGameState
	Method RegisterGameState(name:String, ref:TGameState) 
		mapGS.Insert(name, ref)
	End Method
	
	' SetGameState
	Method SetGameState(gs:TGameState)
		' Quit old game state
		If Self.gameState <> Null
			Self.gameState.Remove()
		EndIf
		
		' Change game state
		Self.gameState = gs
		
		' Init new game state
		If Self.gameState <> Null
			If Self.logger <> Null
				Self.logger.Write("Changing game state to: " + Self.gameState.ToString())
			EndIf
			Self.gameState.Init()
		EndIf
	End Method
	
	' SetGameStateByName
	Method SetGameStateByName(name:String) 
		Self.SetGameState(TGameState(Self.mapGS.ValueForKey(name)))
	End Method
	
	' Run
	Method Run()
		While Self.gameState <> Null And AppTerminate() = 0
			Self.frameTime = MilliSecs() - Self.lastFrameTimeUpdate
			Self.speed = Self.frameTime
			
			Self.lastFrameTimeUpdate = MilliSecs()
			
			If Self.speed <> 0
				If Self.speed > 40
					Self.loggerDetail.Write("FrameTime = " + Self.frameTime)
				EndIf
				Self.gameState.Update()
			Else
				Self.loggerDetail.Write("FrameTime = 0")
				Delay 1
			EndIf
		Wend
	End Method
	
	' Remove
	Method Remove()
		Self.SetGameState(Null)
		Self.logger.Remove()
	End Method
	
	' SetVideoMode
	Method SetVideoMode(width:Int, height:Int, nFullscreen:Int, nDriver:String)
		' Desktop size
		If width = -1
			width = DesktopWidth()
		EndIf
		If height = -1
			height = DesktopHeight()
		EndIf
		
		' Assign values
		Self.gfxWidth = width
		Self.gfxHeight = height
		Self.gfxWidthHalf = width / 2
		Self.gfxHeightHalf = height / 2
		Self.fullscreen = nFullscreen
		
		' Select driver
		If nDriver.Find("Direct") = -1
			Self.driver = "OpenGL"
		Else
			Self.driver = "Direct3D"
		EndIf
	End Method
	
	' Create
	Function Create:TGame()
		Local game:TGame = New TGame
		game.Init()
		Return game
	End Function
End Type
